/*
 *  Copyright 2012 yura.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package org.opu.pc.domain.domains;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.hibernate.annotations.Check;


/**
 * The main purples of this class is to store "Библиографическая ссылка".
 * <br>
 * {@code
 * Библиографическая ссылка – ссылка на публикацию, которая состоит из
 * следующих частей: <Автор/авторы> <Название статьи> <Где издан> <Число,
 * месяц и год> <Где проходила конференция>  <Номер страницы с началом статьи>.
 * }
 * <br>
 * <br>
 * Пример такой ссылки:
 * <br>
 * <pre>
 * Рувинская В.М., Заболотный С.В. Средства разработки планирующих экспертных
 * систем / Труды двенадцатой международной научно-практической конференции
 * «Современные информационные и электронные технологии», 23-27 мая, 2011 г.,
 * Одесса, Украина, с. 82.
 * </pre>
 *
 * It's a good idea to store this link and also store parsed value.
 * 
 * @author yura
 */
@Entity
@Table(name = "publication")
public class Publication implements AbstractDomain<Integer>, Serializable {

	private static final long serialVersionUID = 5309518646666592730L;

    /**
     * The unique identifier of each publication
     */
	@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;

    /**
     * The authors of this publication
     */
    @ManyToMany
    @JoinTable(name = "publication_publicators",
        joinColumns=
            @JoinColumn(name = "publication_id", referencedColumnName = "id"),
        inverseJoinColumns=
            @JoinColumn(name = "publicators_id", referencedColumnName = "id"))
    private Set<Publisher> publishers = new HashSet<Publisher>();

    /**
     * The name of the publication
     */
    @Column(name = "name")
    private String name;

    /**
     * Where the article was published
     */
    @Column(name = "publication_place")
    private String publicationPlace;

    /**
     * Day, month and year
     */
    @Temporal(TemporalType.DATE)
    @Column(name = "publication_date")
    private Date date = new Date();

    /**
     * The conference venue
     * (Place where conference was)
     */
    @Column(name = "conference_venue")
    private String conferenceVenue;

    /**
     * The page number from the beginning of the article
     */
    @Check(constraints="page_number > -2")
    @Column(name = "page_number_start", nullable=false)
    private Integer pageNumberStart = Integer.valueOf(-1);

    @Check(constraints="page_number > -2")
    @Column(name = "page_number_end", nullable=false)
    private Integer pageNumberEnd = Integer.valueOf(-1);

    /**
     * Высшая аттестационная комиссия (ВАК) - центральный государственный орган
     * в области присуждения учёных степеней и званий. В Украине была
     * ликвидирована 10 декабря 2010 года по указу президента Украины. Её права
     * были переедены Министерству образования, науки, молодёжи и спорту Украины.
     *
     * ВАК публикация – публикация статьи в журнале(или в каком то другом
     * сборнике), рекомендованном ВАК(или Министерством образования).
     */
    @Column(name = "was_applied", nullable=false)
    private Boolean wasApplied = Boolean.FALSE;

//    @Lob
//    @Basic(fetch=FetchType.LAZY)
//    @Column(name = "publication_data")
//    private Blob data;//org.postgresql.jdbc4.Jdbc4Blob

    @Override
    public Integer getId() {
        return id;
    }

    @Override
    public void setId(Integer id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Set<Publisher> getPublishers() {
        return publishers;
    }

    public void setPublishers(Set<Publisher> publicators) {
        this.publishers = publicators;
    }

    public Boolean isWasApplied() {
        return wasApplied;
    }

    public void setWasApplied(Boolean wasApplied) {
        this.wasApplied = wasApplied;
    }

    public boolean wasApplied() {
        return wasApplied != null ? wasApplied : false;
    }

//    public Blob getData() {
//        return data;
//    }
//
//    @SuppressWarnings("deprecation")
//	public void setData(byte[] data) {
//        this.data = Hibernate.createBlob(data);
//    }
//
//    public void setData(byte[] data, Session session) {
//        this.data = Hibernate.createBlob(data, session);
//    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getConferenceVenue() {
        return conferenceVenue;
    }

    /**
     * @see #conferenceVenue
     * @param conferenceVenue
     */
    public void setConferenceVenue(String conferenceVenue) {
        this.conferenceVenue = conferenceVenue;
    }

    public Integer getPageNumberStart() {
        return pageNumberStart;
    }

    public void setPageNumberStart(Integer pageNumber) {
        this.pageNumberStart = pageNumber;
        if (pageNumberEnd == null || pageNumberEnd < pageNumber) {
            pageNumberEnd = new Integer(pageNumber.intValue());
        }
    }

    public Integer getPageNumberEnd() {
        return pageNumberEnd;
    }

    public void setPageNumberEnd(Integer pageNumberEnd) {
        this.pageNumberEnd = pageNumberEnd;
    }

    public String getPublicationPlace() {
        return publicationPlace;
    }

    public void setPublicationPlace(String publicationPlace) {
        this.publicationPlace = publicationPlace;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Publication other = (Publication) obj;
        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        return "Publication{" + "name=" + name + '}';
    }
}
